////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//	MathMatrix4x4.h
//  MathLib
//
//  Created by Gregory Maks on 8/14/09.
//  Copyright 2010 Immersion Digital. All rights reserved.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef MATH_MATRIX_H
#define MATH_MATRIX_H

#include "MathDefines.h"



// Predefinitions
class Math;
struct Vector4;
struct Quaternion;


// Typedefs
typedef enum MatrixArrayType
{
	MatrixArrayType_ColumnMajor,
	MatrixArrayType_RowMajor
} MatrixArrayType;


// Column-major matrix [column][row]
struct Matrix4x4
{
public:
	// vars
	floatType n[4][4];
	
	// constructors
	/// Initializes matrix with Identity
	Matrix4x4 ();
	Matrix4x4 (floatType *array, MatrixArrayType arrType);
	
public:
	/// Clears matrix (all cells are set to 0)
	void ctor ();
	
	// matrix creation methods
	void InitWithIdentity ();
	void InitWithData (floatType *array, MatrixArrayType arrType);
	/// Initializes a rotation matrix around one of 3 axes (X, Y, Z)
	void InitWithRotation (AxisType axis, floatType angle);
	/// Initializes matrix with rotation around specified axis
	void InitWithRotation (Vector4 &axis, floatType angle);
	/// Initializes matrix with rotation specified in yaw, pitch, roll angles
	void InitWithRotationYawPitchRoll (floatType yaw, floatType pitch, floatType roll);
	void InitWithTranslation (floatType x, floatType y, floatType z);
	void InitWithScaling (floatType sizeX, floatType sizeY, floatType sizeZ);
	void InitWithQuaternion (Quaternion &quat);
	void InitWithUnitQuaternion (Quaternion &quat);
	
	void InitWithLookAt (floatType eyex, floatType eyey, floatType eyez, 
						 floatType centerx, floatType centery, floatType centerz, 
						 floatType upx, floatType upy, floatType upz);
	
	void InitWithPerspective (floatType fovy, floatType aspect, floatType zNear, floatType zFar);
	void InitWithOrtho (floatType leftPlane, floatType rightPlane, 
						floatType bottomPlane, floatType topPlane,
						floatType nearPlane, floatType farPlane);
	
	// properties
	bool IsIdentity ();
	
	// methods
	floatType Determinant ();
	void Inverse ();
	void Transpose ();
	void Multiply (Matrix4x4 &mat);
	
	void ConvertToColumnMajorArray (float *array);
	void ConvertToRowMajorArray (float *array);
	
	// debug methods
	void Printf();
	
	// operators
	Matrix4x4 operator* (Matrix4x4 &mat);
	Matrix4x4& operator*= (Matrix4x4 &mat);
	
	bool operator== (Matrix4x4 &mat);
	bool operator!= (Matrix4x4 &mat);
	

private:
	void GetMinorMatrix(floatType *src, floatType *dest, int row, int col, int order);
	floatType CalcCustomDeterminant (floatType *mat, int order);
	
};

/* To implement
 D3DXMatrixDecompose - decomposing on rotation, translation and scale components
 */



#endif //MATH_MATRIX_H



























